home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / stencil / outline.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  7KB  |  275 lines

  1. /*
  2.  * Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /* outline.c
  18.  * outline.c draws two outlined rotating torii .
  19.  */
  20.  
  21. #include <gl/gl.h>
  22. #include <gl/device.h>
  23. #include <stdio.h>
  24. #include <math.h>
  25.  
  26. void def_simple_light_calc(void);
  27. void use_simple_light_calc(void);
  28. void main(void);
  29. void initialize(void);
  30. void drawscene(void);
  31.  
  32. float shiny_material[] = {
  33.     DIFFUSE, 0.4, 0.4, 0.4,
  34.     SPECULAR, 1.0, 1.0, 1.0,
  35.     SHININESS, 128.0,
  36.     LMNULL };
  37.  
  38. float blue_material[] = {
  39.     DIFFUSE, 0.0, 0.0, 0.4,
  40.     SPECULAR, 0.0, 1.0, 1.0,
  41.     SHININESS, 45.0,
  42.     LMNULL };
  43.  
  44. void
  45. def_simple_light_calc(void)
  46. {
  47.     lmdef(DEFMATERIAL, 1, 11, shiny_material);
  48.     lmdef(DEFMATERIAL, 2, 11, blue_material);
  49.     lmdef(DEFLIGHT, 1, 0, NULL);
  50.     lmdef(DEFLMODEL, 1, 0, NULL);
  51. }
  52.  
  53. void
  54. use_simple_light_calc(void)
  55. {
  56.     lmbind(LIGHT0, 1);
  57.     lmbind(LMODEL, 1);
  58. }
  59.  
  60. /* three dimensional vector */
  61. typedef float vector[3];
  62.  
  63. /* number of polygons around the cross section of the torus */
  64. #define TORUS_NUMC 10
  65.  
  66. /* number of polygons around the outside of the torus */
  67. #define TORUS_NUMT 20
  68.  
  69. /* default torus cross sectional radius */
  70. #define TORUS_RAD_XC 0.3
  71.  
  72. /* default torus radius */
  73. #define TORUS_RAD 1.0
  74.  
  75. /* arrays for torus vertices and normals */
  76. static vector torus_point[TORUS_NUMC][TORUS_NUMT];
  77. static vector torus_norm[TORUS_NUMC][TORUS_NUMT];
  78.  
  79. /* has the torus been initialized yet */
  80. static Boolean torus_initialized = FALSE;
  81.  
  82.  
  83. /* initalize data for a torus */
  84. static void inittorus(
  85.         float rc,        /* radius of the cross section */
  86.         float rt,        /* radius of the torus */
  87.         vector point[TORUS_NUMC][TORUS_NUMT], /* array of vertices */
  88.         vector norm[TORUS_NUMC][TORUS_NUMT])  /* array of normals */
  89. {
  90.         int i, j;
  91.         int numc = TORUS_NUMC, numt = TORUS_NUMT;
  92.         float twopi, fi, fj, xc, yc, nx, ny, nz, n;
  93.  
  94.         twopi = 2.0 * M_PI;
  95.  
  96.         /* go around cross section */
  97.         for (i = 0; i < numc; i++) {                
  98.             fi =(float) i;
  99.           
  100.               /* go around top view         */
  101.             for (j = 0; j < numt; j++) {        
  102.                 fj =(float) j;
  103.  
  104.                 point[i][j][0] = (rt + rc*fcos(twopi * fi/numc))
  105.                    * fcos(twopi * fj/numt);
  106.                 point[i][j][1] = (rt + rc*fcos(twopi * fi/numc))
  107.                    * fsin(twopi * fj/numt);
  108.                 point[i][j][2] = rc * fsin(twopi * fi/numc);
  109.  
  110.                 xc = rt*fcos(twopi*fj/numt);
  111.                 yc = rt*fsin(twopi*fj/numt);
  112.                         
  113.                 nx = point[i][j][0] - xc;
  114.                 ny = point[i][j][1] - yc;
  115.                 nz = point[i][j][2];
  116.  
  117.                 n = fsqrt(nx*nx + ny*ny + nz*nz);
  118.  
  119.                 norm[i][j][0] = nx/n;
  120.                 norm[i][j][1] = ny/n;
  121.                 norm[i][j][2] = nz/n;
  122.             }
  123.         }
  124. }
  125.  
  126.  
  127. /* set the cross sectional and torus radius */
  128. void settorus(float rc, float rt)
  129. {
  130.         inittorus(rc,rt,torus_point,torus_norm);
  131.         torus_initialized = TRUE;
  132. }
  133.  
  134. /* filled torus */
  135. void ftorus(void)
  136. {
  137.         int i, j;
  138.         int numc = TORUS_NUMC, numt = TORUS_NUMT;
  139.  
  140.         if (! torus_initialized)
  141.                 settorus(TORUS_RAD_XC,TORUS_RAD);
  142.  
  143.         for (i = 0; i < numc; i++) {
  144.             bgntmesh();
  145.                 n3f(torus_norm[(i+1)%numc][0]);
  146.                 v3f(torus_point[(i+1)%numc][0]);
  147.                 for (j = 0; j < numt; j++) {
  148.                         n3f(torus_norm[i][j]);
  149.                         v3f(torus_point[i][j]);
  150.                         n3f(torus_norm[(i+1)%numc][(j+1)%numt]);
  151.                         v3f(torus_point[(i+1)%numc][(j+1)%numt]);
  152.                 }
  153.                 n3f(torus_norm[i][0]);
  154.                 v3f(torus_point[i][0]);
  155.             endtmesh();
  156.         }
  157. }
  158.  
  159.  
  160.  
  161. void
  162. main(void)
  163. {
  164.     short attached;
  165.     short value;
  166.     int dev;
  167.  
  168.     attached = 1;
  169.  
  170.     if (!getgdesc(GD_POLYMODE)) {
  171.         fprintf(stderr, "This machine does not support polymode.\n");
  172.         exit(0);
  173.     }
  174.  
  175.     initialize();
  176.  
  177.     while (TRUE) {
  178.         while (qtest() || !attached) {
  179.             dev = qread (&value);
  180.             if ((dev == ESCKEY) && (value == 0))
  181.                 exit(0);
  182.             else if (dev == REDRAW) {
  183.                 reshapeviewport();
  184.                 drawscene();
  185.             }
  186.             else if (dev == INPUTCHANGE)
  187.                 attached = value;    
  188.         }    /*  end while qtest or not attached  */
  189.         drawscene();
  190.     }    /*  end while (TRUE)  */
  191. }    /*  end main()  */
  192.  
  193.  
  194. /*    The initialize subroutine positions the window and specifies
  195.  *    its future constraints.  The program is in double buffer
  196.  *    and RGB mode.  The simplest lighting model is used. 
  197.  */ 
  198. void
  199. initialize(void)
  200. {
  201.     long gid1;
  202.     long xmax, ymax;
  203.  
  204.     xmax = getgdesc(GD_XPMAX);
  205.     ymax = getgdesc(GD_YPMAX);
  206.     prefposition( xmax/4, xmax*3/4, ymax/4, ymax*3/4 );
  207.     gid1 = winopen ("outline");
  208.     minsize (xmax/10, ymax/10);
  209.     keepaspect (xmax, ymax);
  210.     winconstraints();
  211.  
  212.     doublebuffer();
  213.     RGBmode();
  214.     stensize ( 1 );
  215.     gconfig();
  216.     zbuffer(TRUE);
  217.     subpixel(TRUE);
  218.  
  219.     qdevice (ESCKEY);
  220.     qenter (REDRAW, gid1);
  221.  
  222.     mmode(MVIEWING);
  223.     perspective( 450, (float)xmax/(float)ymax, 3.0, 7.0);
  224.     lookat(2.5, 0.0, 5.0, 0.0, 0.0, 0.0, 0);
  225.  
  226.     def_simple_light_calc();
  227.     use_simple_light_calc();
  228.  
  229. }
  230.  
  231. /*    Draw 2 outlined rotating torii 
  232.  */
  233. void
  234. drawscene(void)
  235. {
  236.     static Angle angle = 0;         /* counter for angle rotation */
  237.  
  238.     czclear(0x0, getgdesc(GD_ZMAX));
  239.  
  240.     /* draw them filled */
  241.     polymode( PYM_FILL );
  242.  
  243.     pushmatrix();
  244.         rotate(angle * 2, 'z');
  245.         rotate(angle * 2, 'y');
  246.         lmbind(MATERIAL,1);
  247.         ftorus();
  248.         pushmatrix();
  249.             rotate(900, 'x');
  250.             ftorus();
  251.         popmatrix();
  252.     popmatrix();
  253.  
  254.     /* draw them hollow */
  255.     sclear(0x0);    /* for PYM_HOLLOW */
  256.     stencil (TRUE, 1, SF_EQUAL, 0x1, ST_KEEP, ST_KEEP, ST_REPLACE);
  257.     polymode( PYM_HOLLOW );
  258.  
  259.     pushmatrix();
  260.         rotate(angle * 2, 'z');
  261.         rotate(angle * 2, 'y');
  262.         lmbind(MATERIAL,2);
  263.         ftorus();
  264.         pushmatrix();
  265.             rotate(900, 'x');
  266.             ftorus();
  267.         popmatrix();
  268.     popmatrix();
  269.  
  270.     stencil (FALSE, 1, SF_EQUAL, 0x1, ST_KEEP, ST_KEEP, ST_REPLACE);
  271.  
  272.     swapbuffers();
  273.     angle = angle + 10;
  274. }
  275.